package com.billy.ohos.swipe.demo;

import com.billy.ohos.swipe.SmartSwipe;
import com.billy.ohos.swipe.SmartSwipeWrapper;
import com.billy.ohos.swipe.SwipeConsumer;
import com.billy.ohos.swipe.consumer.*;
import com.billy.ohos.swipe.demo.consumer.*;
import com.billy.ohos.swipe.demo.util.ResourceUtil;
import com.billy.ohos.swipe.internal.LogUtil;
import com.billy.ohos.swipe.listener.SimpleSwipeListener;
import ohos.aafwk.ability.Ability;
import ohos.aafwk.content.Intent;
import ohos.aafwk.content.Operation;
import ohos.agp.components.*;
import ohos.media.image.PixelMap;

import java.text.DecimalFormat;
import java.text.NumberFormat;

public class MainAbility extends BaseAbility {

    private NumberFormat formatter = new DecimalFormat("0.00");
    private SwipeConsumer mCurrentDrawerConsumer;
    private DrawerConsumer mDrawerConsumer;
    private SlidingConsumer mSlidingConsumer;
    private Text mTvMainConsumerName;
    private Component mMainConsumerSlidePanel;
    private Text mTvMainConsumerSlideFactor;
    private Slider mSlideFactorSeekBar;
    private Text mTvMainConsumerEdgeSize;
    private Slider mEdgeSizeSeekBar;

    Text shuttersLeavesCountTextView;
    Checkbox shuttersRefreshableCheckBox;
    Slider shuttersSeekBar;
    Checkbox doorRefreshableCheckBox;

    private boolean mIsMenuMode;
    private CoverManager mCoverManager;
    private FallingView fallingView;
    private Component horizontalMenu;
    private SmartSwipeWrapper wrapper;
    private Component topMenu;
    private Component bottomMenu;
    private SmartSwipeWrapper topMenuWrapper;
    private SmartSwipeWrapper horizontalMenuWrapper;
    private SmartSwipeWrapper bottomMenuWrapper;
    private SimpleSwipeListener listener;

    @Override
    public void onStart(Intent intent) {
        super.onStart(intent);
        ComponentContainer parse = (ComponentContainer) LayoutScatter.getInstance(this)
                .parse(ResourceTable.Layout_ability_main, null, false);
        super.setUIContent(parse);
        initViews();
        LogUtil.loge("onFinishInflate", "mainAbility");
        initCover();
        initSideMenu();
        initListeners();
        toggleConsumer();

    }


    @Override
    protected void onActive() {
        super.onActive();
    }

    private void initCover() {
        PixelMap pixelMapFromRes = ResourceUtil.getPixelMapFromRes(this, ResourceTable.Media_icon_snow);
        fallingView = (FallingView) findComponentById(ResourceTable.Id_falling_view);
        fallingView.addFallObject(100, new FallingView.FallObject.Builder(pixelMapFromRes)
                .setSpeed(100, true)
                .setSize(50, 50, true)
                .setWind(5, true, true)
        );

        //manage the app cover
        Component mCover = findComponentById(ResourceTable.Id_cover);
        mCoverManager = CoverManager.manage(mCover)
                .setWidth(screenWidth)
                .setHeight(screenHeight)
                .setCoverListener(new CoverManager.CoverListener() {
                    @Override
                    public void onOpened() {
                        if (mCurrentDrawerConsumer != null) {
                            mCurrentDrawerConsumer.unlockAllDirections();
                        }
                        fallingView.refresh();
                        fallingView.stopFalling();
                    }

                    @Override
                    public void onClosed() {
                        if (mCurrentDrawerConsumer != null) {
                            mCurrentDrawerConsumer.lockAllDirections();
                        }
                        fallingView.startFalling();
                    }
                })
        ;
    }

    private void initSideMenu() {
        // demo to specified size of drawer
        int size = SmartSwipe.dp2px(300, this);

        // create horizontal menu view: stretch top & bottom
        horizontalMenu = LayoutScatter.getInstance(this).parse(ResourceTable.Layout_layout_main_menu, null, false);
        horizontalMenu.setLayoutConfig(new ComponentContainer.LayoutConfig(size, ComponentContainer.LayoutConfig.MATCH_PARENT));
        horizontalMenuWrapper = SmartSwipe.wrapView(horizontalMenu).addConsumer(new StretchConsumer()).enableVertical().getWrapper();
        horizontalMenuWrapper.setTag("horizontalMenu");

        // create top menu view: Space on top drag
        topMenu = LayoutScatter.getInstance(this).parse(ResourceTable.Layout_layout_main_menu, null, false);
        topMenu.setLayoutConfig(new StackLayout.LayoutConfig(StackLayout.LayoutConfig.MATCH_PARENT, size));
        initWrapper();
        // create bottom menu view: Space on bottom drag
        bottomMenu = LayoutScatter.getInstance(this).parse(ResourceTable.Layout_layout_main_menu, null, false);
        bottomMenu.setLayoutConfig(new StackLayout.LayoutConfig(StackLayout.LayoutConfig.MATCH_PARENT, size));
        bottomMenuWrapper = SmartSwipe.wrapView(bottomMenu).addConsumer(new SpaceConsumer()).enableBottom().getWrapper();
        listener = new SimpleSwipeListener() {
            @Override
            public void onSwipeOpened(SmartSwipeWrapper wrapper, SwipeConsumer consumer, int direction) {
                super.onSwipeOpened(wrapper, consumer, direction);
                setLeftBtnImage(false);
            }

            @Override
            public void onSwipeClosed(SmartSwipeWrapper wrapper, SwipeConsumer consumer, int direction) {
                super.onSwipeClosed(wrapper, consumer, direction);
                setLeftBtnImage(true);
            }
        };
        initDrawerConsumer();
        initSlidingConsumer();
    }

    private void initSlidingConsumer() {
        mSlidingConsumer = new SlidingConsumer()
                .setDrawerExpandable(true)
                // horizontal menu
                .setHorizontalDrawerView(horizontalMenuWrapper)
                // top menu
                .setTopDrawerView(topMenuWrapper)
                // bottom menu
                .setBottomDrawerView(bottomMenuWrapper)
                .showScrimAndShadowOutsideContentView()
                // set the translucent color of scrim (default is 0:transparent)
                .setScrimColor(0x7F000000)
                .setShadowSize(SmartSwipe.dp2px(10, this))
                .setShadowColor(0x80000000)
                .addListener(listener)
                // set edge size to swipe to 20dp (default is 0: whole range of the contentView bounds)
                .setEdgeSize(SmartSwipe.dp2px(20, this))
                .as(SlidingConsumer.class);
        // horizontalMenuWrapper.onFinishInflate();
        // topMenuWrapper.onFinishInflate();
        // bottomMenuWrapper.onFinishInflate();
    }

    private void initDrawerConsumer() {
        mDrawerConsumer = new DrawerConsumer()
                // horizontal menu
                .setHorizontalDrawerView(horizontalMenuWrapper)
                // top menu
                .setTopDrawerView(topMenuWrapper)
                // bottom menu
                .setBottomDrawerView(bottomMenuWrapper)
                // .showScrimAndShadowOutsideContentView()
                // set the translucent color of scrim (default is 0:transparent)
                .setScrimColor(0x7F000000)
                // set the shadow color follow the drawer while swiping (default is 0:transparent)
                .setShadowColor(0x80000000)
                .setShadowSize(SmartSwipe.dp2px(10, this))
                .addListener(listener)
                // set edge size to swipe to 20dp (default is 0: whole range of the contentView bounds)
                .setEdgeSize(SmartSwipe.dp2px(20, this))
                .as(DrawerConsumer.class);
    }

    private void initWrapper() {
        // SmartSwipeWrapper topMenuWrapper = SmartSwipe.wrap(topMenu).addConsumer(new SpaceConsumer()).enableTop().getWrapper();
        topMenuWrapper = SmartSwipe.wrapView(topMenu)
                .addConsumer(new SpaceConsumer())
                .enableTop()
                // enable & lock bottom, and enable bottom nested fly,
                // let it to consume bottom nested fly event
                // try it with demo apk!
                .enableBottom().enableNestedScrollBottom(false).enableNestedFlyBottom(true)
                .addListener(new SimpleSwipeListener() {

                    @Override
                    public void onSwipeStart(SmartSwipeWrapper wrapper, SwipeConsumer consumer, int direction) {
                        if (direction == SwipeConsumer.DIRECTION_BOTTOM) {
                            wrapper.setNestedScrollingEnabled(false);
                        }
                    }

                    @Override
                    public void onSwipeClosed(SmartSwipeWrapper wrapper, SwipeConsumer consumer, int direction) {
                        wrapper.setNestedScrollingEnabled(true);
                    }
                })
                .getWrapper();
        topMenuWrapper.setTag("top");
    }

    @Override
    protected void onStop() {
        if (fallingView != null) {
            fallingView.stopFalling();
        }
        super.onStop();
    }

    private void setLeftBtnImage(boolean menuMode) {
        if (menuMode ^ mIsMenuMode) {
            mIsMenuMode = menuMode;
            setLeftBtnImage(menuMode ? ResourceTable.Media_icon_menu : ResourceTable.Media_icon_back);
        }
    }

    private void initViews() {
        mTvMainConsumerName = (Text) findComponentById(ResourceTable.Id_main_ui_name);
        mMainConsumerSlidePanel = findComponentById(ResourceTable.Id_main_ui_slide_panel);
        mTvMainConsumerSlideFactor = (Text) findComponentById(ResourceTable.Id_main_ui_slide_factor);
        mSlideFactorSeekBar = (Slider) findComponentById(ResourceTable.Id_main_ui_slide_factor_seek_bar);
        mTvMainConsumerEdgeSize = (Text) findComponentById(ResourceTable.Id_main_ui_edge_size);
        mEdgeSizeSeekBar = (Slider) findComponentById(ResourceTable.Id_main_ui_edge_size_seek_bar);

        // demo to use SmartSwipe within xml layout
        wrapper = (SmartSwipeWrapper) findComponentById(ResourceTable.Id_main_ui_wrap_view);
        wrapper.addConsumer(new SlidingConsumer()).setRelativeMoveFactor(SlidingConsumer.FACTOR_FOLLOW);

        wrapper.setTag("likeButton");

        shuttersLeavesCountTextView = (Text) findComponentById(ResourceTable.Id_cover_shutters_leaves_count_number);
        shuttersRefreshableCheckBox = (Checkbox) findComponentById(ResourceTable.Id_cover_shutters_refreshable);

        shuttersSeekBar = (Slider) findComponentById(ResourceTable.Id_cover_shutters_leaves_count_seek_bar);
        doorRefreshableCheckBox = (Checkbox) findComponentById(ResourceTable.Id_cover_door_refreshable);
        setLeftBtnImage(true);
    }

    private void initListeners() {

        mSlideFactorSeekBar.setValueChangedListener(new Slider.ValueChangedListener() {
            @Override
            public void onProgressUpdated(Slider slider, int progress, boolean b) {
                mSlidingConsumer.setRelativeMoveFactor(progress * 0.01F);
                float result = mSlidingConsumer.getRelativeMoveFactor();

                LogUtil.loge("onProgressUpdated","onProgressUpdated result======   " + result);
                mTvMainConsumerSlideFactor.setText(formatter.format(result));
            }

            @Override
            public void onTouchStart(Slider slider) {

            }

            @Override
            public void onTouchEnd(Slider slider) {

            }
        });
        mEdgeSizeSeekBar.setValueChangedListener(new Slider.ValueChangedListener() {
            @Override
            public void onProgressUpdated(Slider slider, int progress, boolean b) {
                mCurrentDrawerConsumer.setEdgeSize(progress);
                if (progress == 0) {
                    mTvMainConsumerEdgeSize.setText(ResourceTable.String_demo_main_group_ui_edge_full);
                } else {
                    mTvMainConsumerEdgeSize.setText(progress + "px");
                }
            }

            @Override
            public void onTouchStart(Slider slider) {

            }

            @Override
            public void onTouchEnd(Slider slider) {

            }
        });
        findComponentById(ResourceTable.Id_main_ui_toggle).setClickedListener(new Component.ClickedListener() {
            @Override
            public void onClick(Component component) {
                toggleConsumer();
            }
        });


        // click  view
        shuttersRefreshableCheckBox.setClickedListener(this::toggleShuttersRefresh);
        doorRefreshableCheckBox.setClickedListener(this::toggleShuttersRefresh);
        findComponentById(ResourceTable.Id_showDoorCover).setClickedListener(this::showDoorCover);
        findComponentById(ResourceTable.Id_showDrawerCover).setClickedListener(this::showDrawerCover);
        findComponentById(ResourceTable.Id_showShuttersCover).setClickedListener(this::showShuttersCover);
        setCllick(horizontalMenu);
        setCllick(topMenu);
        setCllick(bottomMenu);


    }

    private void setCllick(Component horizontalMenu) {
        horizontalMenu.findComponentById(ResourceTable.Id_toSpaceConsumerAbility).setClickedListener(this::toSpaceConsumerAbility);
        horizontalMenu.findComponentById(ResourceTable.Id_toStretchConsumerAbility).setClickedListener(this::toStretchConsumerAbility);
        horizontalMenu.findComponentById(ResourceTable.Id_toDrawerConsumerAbility).setClickedListener(this::toDrawerConsumerAbility);
        horizontalMenu.findComponentById(ResourceTable.Id_toBezierConsumerAbility).setClickedListener(this::toBezierConsumerAbility);
        horizontalMenu.findComponentById(ResourceTable.Id_toStayConsumerAbility).setClickedListener(this::toStayConsumerAbility);
        horizontalMenu.findComponentById(ResourceTable.Id_toSwipeBackTranslucentConsumerAbility).setClickedListener(this::toSwipeBackTranslucentConsumerAbility);
        horizontalMenu.findComponentById(ResourceTable.Id_toSlideConsumerAbility).setClickedListener(this::toSlideConsumerAbility);
        horizontalMenu.findComponentById(ResourceTable.Id_toTranslucentConsumerAbility).setClickedListener(this::toTranslucentConsumerAbility);
        horizontalMenu.findComponentById(ResourceTable.Id_toDoorConsumerAbility).setClickedListener(this::toDoorConsumerAbility);
        horizontalMenu.findComponentById(ResourceTable.Id_toAbilityDoorBackConsumerAbility).setClickedListener(this::toAbilityDoorBackConsumerAbility);
        horizontalMenu.findComponentById(ResourceTable.Id_toShuttersConsumerAbility).setClickedListener(this::toShuttersConsumerAbility);
        horizontalMenu.findComponentById(ResourceTable.Id_toAbilityShuttersBackConsumerAbility).setClickedListener(this::toAbilityShuttersBackConsumerAbility);
    }

    private void toggleConsumer() {
        SwipeConsumer consumer = mCurrentDrawerConsumer == mSlidingConsumer ? mDrawerConsumer : mSlidingConsumer;
        // add swipe consumer to this ability
        mCurrentDrawerConsumer = SmartSwipe.wrap(contentView)
                // remove current consumer
                .removeConsumer(mCurrentDrawerConsumer)
                // add new consumer to this ability wrapper
                .addConsumer(consumer);
        mTvMainConsumerName.setText(mCurrentDrawerConsumer.getClass() == SlidingConsumer.class ? ResourceTable.String_demo_ui_SlidingConsumer : ResourceTable.String_demo_ui_DrawerConsumer);
        mMainConsumerSlidePanel.setVisibility(mCurrentDrawerConsumer == mSlidingConsumer ? Component.VISIBLE : Component.HIDE);
        mEdgeSizeSeekBar.setProgressValue(mCurrentDrawerConsumer.getEdgeSize());
        Component avatarView = findComponentById(ResourceTable.Id_avatar);
        if (avatarView != null) {
            avatarView.setClickedListener(new Component.ClickedListener() {
                @Override
                public void onClick(Component component) {
                    forwardToAbility(SwipeBackTranslucentConsumerAbility.class);
                }
            });
        }
        if (mCurrentDrawerConsumer == mSlidingConsumer) {
            float factor = mSlidingConsumer.getRelativeMoveFactor();
            mTvMainConsumerSlideFactor.setText(String.valueOf(factor));
            mSlideFactorSeekBar.setProgressValue((int) (factor * 100));
        }
    }

    @Override
    public int getTitleResId() {
        return ResourceTable.String_app_name;
    }

    @Override
    protected void onLeftTitleBtnClick() {
        if (mIsMenuMode) {
            mCurrentDrawerConsumer.smoothLeftOpen();
        } else {
            mCurrentDrawerConsumer.smoothClose();
        }
    }

    private void refreshCoverOptionPanel() {
        if (mCurrentDrawerConsumer != null) {
            mCurrentDrawerConsumer.lockAllDirections();
        }
        Class<? extends SwipeConsumer> clazz = mCoverManager.consumer.getClass();
        findComponentById(ResourceTable.Id_panel_shutters).setVisibility(clazz == ShuttersConsumer.class ? Component.VISIBLE : Component.INVISIBLE);
        findComponentById(ResourceTable.Id_panel_door).setVisibility(clazz == DoorConsumer.class ? Component.VISIBLE : Component.INVISIBLE);
        if (clazz == ShuttersConsumer.class) {
            ShuttersConsumer consumer = (ShuttersConsumer) mCoverManager.consumer;
            shuttersLeavesCountTextView.setText(String.valueOf(consumer.getLeavesCount()));
            shuttersRefreshableCheckBox.setChecked(consumer.isRefreshable());
            shuttersSeekBar.setProgressValue(consumer.getLeavesCount());
            shuttersSeekBar.setValueChangedListener(new Slider.ValueChangedListener() {
                @Override
                public void onProgressUpdated(Slider slider, int progress, boolean b) {
                    ShuttersConsumer consumer = (ShuttersConsumer) mCoverManager.consumer;
                    consumer.setLeavesCount(progress);
                    shuttersLeavesCountTextView.setText(String.valueOf(consumer.getLeavesCount()));
                }

                @Override
                public void onTouchStart(Slider slider) {

                }

                @Override
                public void onTouchEnd(Slider slider) {

                }
            });
        } else if (clazz == DoorConsumer.class) {
            DoorConsumer consumer = (DoorConsumer) mCoverManager.consumer;
            doorRefreshableCheckBox.setChecked(consumer.isRefreshable());
        }
    }

    public void toggleShuttersRefresh(Component view) {
        if (view instanceof Checkbox && mCoverManager.consumer instanceof ShuttersConsumer) {
            ((ShuttersConsumer) mCoverManager.consumer).setRefreshable(((Checkbox) view).isChecked());
        }
    }

    @Override
    public void onBackPressed() {
        if (mCoverManager != null && !mCoverManager.isOpened()) {
            // open the cover automatically
            mCoverManager.open();
        } else if (mCurrentDrawerConsumer != null && !mCurrentDrawerConsumer.isClosed()) {
            // close the drawer automatically
            mCurrentDrawerConsumer.close(true);
        } else {
            // finish ability
            terminateAbility();
        }
    }

    private void forwardToAbility(Class<? extends Ability> clazz) {
        // startAbility(new Intent(this, clazz));
        Intent intent = new Intent();
        Operation operation = new Intent.OperationBuilder()
                .withBundleName(getBundleName())
                .withAbilityName(clazz.getName())
                .build();
        intent.setOperation(operation);
        startAbility(intent);
    }

    public void toSpaceConsumerAbility(Component view) {
        forwardToAbility(SpaceConsumerAbility.class);
    }

    public void toStretchConsumerAbility(Component view) {
        forwardToAbility(StretchConsumerAbility.class);
    }

    public void toDrawerConsumerAbility(Component view) {
        forwardToAbility(DrawerConsumerAbility.class);
    }

    public void toBezierConsumerAbility(Component view) {
        forwardToAbility(SwipeBackBezierConsumerAbility.class);
    }

    public void toStayConsumerAbility(Component view) {
        forwardToAbility(SwipeBackStayConsumerAbility.class);
    }

    public void toSwipeBackTranslucentConsumerAbility(Component view) {
        forwardToAbility(SwipeBackTranslucentConsumerAbility.class);
    }

    public void toSlideConsumerAbility(Component view) {
        forwardToAbility(SlidingConsumerAbility.class);
    }

    public void toTranslucentConsumerAbility(Component view) {
        forwardToAbility(TranslucentConsumerAbility.class);
    }

    public void toDoorConsumerAbility(Component view) {
        forwardToAbility(DoorConsumerAbility.class);
    }

    public void toAbilityDoorBackConsumerAbility(Component view) {
        forwardToAbility(SwipeBackDoorConsumerAbility.class);
    }

    public void toShuttersConsumerAbility(Component view) {
        forwardToAbility(ShuttersConsumerAbility.class);
    }

    public void toAbilityShuttersBackConsumerAbility(Component view) {
        forwardToAbility(SwipeBackShuttersConsumerAbility.class);
    }

    public void showShuttersCover(Component view) {
        if (mCoverManager != null) {
            mCoverManager.showShuttersMode();
            refreshCoverOptionPanel();
        }
    }

    public void showDoorCover(Component view) {
        if (mCoverManager != null) {
            mCoverManager.doorMode();
            refreshCoverOptionPanel();
        }
    }

    public void showDrawerCover(Component view) {
        if (mCoverManager != null) {
            mCoverManager.drawerMode();
            refreshCoverOptionPanel();
        }
    }
}
